package com.tushikeji.facecar.activity;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;


import com.guo.android_extend.java.AbsLoop;
import com.guo.android_extend.tools.CameraHelper;
import com.guo.android_extend.widget.CameraFrameData;
import com.guo.android_extend.widget.CameraGLSurfaceView;
import com.guo.android_extend.widget.CameraSurfaceView;
import com.guo.android_extend.widget.CameraSurfaceView.OnCameraListener;
import com.tushikeji.facecar.R;
import com.tushikeji.facecar.db.FaceDB;
import com.tushikeji.facecar.utils.PlayConfBell;
import com.tushikeji.facecar.utils.Zlog;
import com.arcsoft.facerecognition.AFR_FSDKEngine;
import com.arcsoft.facerecognition.AFR_FSDKError;
import com.arcsoft.facerecognition.AFR_FSDKFace;
import com.arcsoft.facerecognition.AFR_FSDKMatching;
import com.arcsoft.facerecognition.AFR_FSDKVersion;
import com.arcsoft.facetracking.AFT_FSDKEngine;
import com.arcsoft.facetracking.AFT_FSDKError;
import com.arcsoft.facetracking.AFT_FSDKFace;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by gqj3375 on 2017/4/28.
 */

public class DetecterActivity extends Activity implements OnCameraListener, View.OnTouchListener, Camera.AutoFocusCallback {
    private final String TAG = this.getClass().getSimpleName();

    private int mWidth, mHeight, mFormat;
    private CameraSurfaceView mSurfaceView;
    private CameraGLSurfaceView mGLSurfaceView;
    private Camera mCamera;


    int mCameraID;
    int mCameraRotate;
    boolean mCameraMirror;
    byte[] mImageNV21 = null;
    FRAbsLoop mFRAbsLoop = null;
    AFT_FSDKFace mAFT_FSDKFace = null;
    Handler mHandler;

    private int nv21Height;
    private int nv21Width;
    private List<FaceDB.FaceRegist> mResgist;

    private Application app;
    private boolean save;
    private Rect[] rects;
    private AFR_FSDKError error;
    private List<AFT_FSDKFace> result = new ArrayList<>();

    private boolean isDetect = false;
    private YuvImage yuv;

    class FRAbsLoop extends AbsLoop {

        AFR_FSDKVersion version = new AFR_FSDKVersion();
        AFR_FSDKEngine engine = new AFR_FSDKEngine();
        private Bitmap face_bitmap;
        private AFR_FSDKFace single_result;
        private AFR_FSDKMatching score;

        @Override
        public void setup() {
            AFR_FSDKError error = engine.AFR_FSDK_InitialEngine(FaceDB.appid, FaceDB.fr_key);
            // Log.d(TAG, "AFR_FSDK_InitialEngine = " + error.getCode());
            error = engine.AFR_FSDK_GetVersion(version);
            //  Log.d(TAG, "FR=" + version.toString() + "," + error.getCode()); //(210, 178 - 478, 446), degree = 1　780, 2208 - 1942, 3370
        }

        @Override
        public void loop() {
            if (mImageNV21 != null && mAFT_FSDKFace != null && !isDetect) {
                isDetect = true;
                mResgist = app.faceDB.mRegister;
                single_result = new AFR_FSDKFace();
                long l = System.currentTimeMillis();
                error = app.face_recognize_engine.AFR_FSDK_ExtractFRFeature(mImageNV21, nv21Width, nv21Height, AFR_FSDKEngine.CP_PAF_NV21, mAFT_FSDKFace.getRect(), mAFT_FSDKFace.getDegree(), single_result);
                Zlog.Log("提取人脸特征耗时" + (System.currentTimeMillis() - l));

                score = new AFR_FSDKMatching();
                save = false;
                float max = 0.6f;
                if (!mResgist.isEmpty()) {
                    for (int i = 0; i < mResgist.size(); i++) {
                        if (!mResgist.get(i).mFaceList.isEmpty()) {
                            long l2 = System.currentTimeMillis();
                            error = app.face_recognize_engine.AFR_FSDK_FacePairMatching(single_result, mResgist.get(i).mFaceList.get(0), score);
                            Zlog.Log("playBell");
                            if (error.getCode() != 0) {
                                continue;
                            }
                            if (max < score.getScore()) {
                                max = score.getScore();
                                Zlog.Log("检索人脸耗时" + (System.currentTimeMillis() - l2));
                                break;
                            }
                        }
                    }

                    if (max > 0.8f) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                PlayConfBell.playBell(DetecterActivity.this, R.raw.baojing2);
                                isDetect = false;
                            }
                        });
                    }
                }

                isDetect = false;
                mImageNV21 = null;
                mAFT_FSDKFace = null;
            }
        }

        @Override
        public void over() {
            AFR_FSDKError error = engine.AFR_FSDK_UninitialEngine();
        }

    }


    private TextView mTextView;
    private TextView mTextView1;
    private ImageView mImageView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        Log.d(TAG, "走入onCreate: ");

        app = (Application) getApplication();
        mCameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
        mCameraRotate = 0;
        mCameraMirror = getIntent().getIntExtra("Camera", 0) == 0 ? false : true;
        mWidth = 640;
        mHeight = 480;
        mFormat = ImageFormat.NV21;
        mHandler = new Handler();

        setContentView(R.layout.activity_camera);
        mGLSurfaceView = (CameraGLSurfaceView) findViewById(R.id.glsurfaceView);
        mGLSurfaceView.setOnTouchListener(this);
        mSurfaceView = (CameraSurfaceView) findViewById(R.id.surfaceView);
        mSurfaceView.setOnCameraListener(this);
        mSurfaceView.setupGLSurafceView(mGLSurfaceView, true, mCameraMirror, mCameraRotate);
        mSurfaceView.debug_print_fps(true, false);


        //snap
        mTextView = (TextView) findViewById(R.id.textView);
        mTextView.setText("");
        mTextView1 = (TextView) findViewById(R.id.textView1);
        mTextView1.setText("");

        mImageView = (ImageView) findViewById(R.id.imageView);

        mFRAbsLoop = new FRAbsLoop();
        mFRAbsLoop.start();
    }


    /* (non-Javadoc)
     * @see android.app.Activity#onDestroy()
     */
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mFRAbsLoop.shutdown();
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }


    @Override
    public Camera setupCamera() {
        // TODO Auto-generated method stub
        mCamera = Camera.open(mCameraID);
        try {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(mWidth, mHeight);
            parameters.setPreviewFormat(mFormat);

            for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
                //    Log.d(TAG, "SIZE:" + size.width + "x" + size.height);
            }

            for (Integer format : parameters.getSupportedPreviewFormats()) {
                //     Log.d(TAG, "FORMAT:" + format);
            }

            List<int[]> fps = parameters.getSupportedPreviewFpsRange();
            for (int[] count : fps) {
                //    Log.d(TAG, "T:");
                for (int data : count) {
                    //    Log.d(TAG, "V=" + data);
                }
            }
            mCamera.setParameters(parameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (mCamera != null) {
            mWidth = mCamera.getParameters().getPreviewSize().width;
            mHeight = mCamera.getParameters().getPreviewSize().height;
        }
        return mCamera;
    }

    @Override
    public void setupChanged(int format, int width, int height) {

    }

    @Override
    public boolean startPreviewLater() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    private boolean isPreview = false;

    @Override
    public Object onPreview(byte[] data, int width, int height, int format, long timestamp) {
        if (!isPreview) {
            isPreview = true;
            result.clear();
            long l = System.currentTimeMillis();
            AFT_FSDKError err = app.face_tracking_engine.AFT_FSDK_FaceFeatureDetect(data, width, height, AFT_FSDKEngine.CP_PAF_NV21, result);
            Zlog.Log("识别人脸耗时" + (System.currentTimeMillis() - l));
            nv21Width = width;
            nv21Height = height;
            mImageNV21 = data.clone();
            if (!result.isEmpty()) {
                mAFT_FSDKFace = result.get(0);
                rects = new Rect[result.size()];
                for (int i = 0; i < result.size(); i++) {
                    rects[i] = new Rect(result.get(i).getRect());
                }

            }
            isPreview = false;
        }

        return rects;
    }

    @Override
    public void onBeforeRender(CameraFrameData data) {

    }

    @Override
    public void onAfterRender(CameraFrameData data) {
        if (data != null && data.getParams() != null) {
            mGLSurfaceView.getGLES2Render().draw_rect((Rect[]) data.getParams(), Color.GREEN, 2);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        CameraHelper.touchFocus(mCamera, event, v, this);
        return false;
    }

    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        if (success) {
            //    Log.d(TAG, "Camera Focus SUCCESS!");
        }
    }
}
